package com.smedi.ismedi.authority.starter.handler;

import com.smedi.ismedi.authority.starter.common.ResponseData;
import com.smedi.ismedi.authority.starter.constant.AuthorityConstant;
import com.smedi.ismedi.authority.starter.exception.BasicError;
import com.smedi.ismedi.authority.starter.exception.LogicException;
import com.smedi.ismedi.authority.starter.feign.AuthorityAccessFeignClient;
import com.smedi.ismedi.authority.starter.property.AuthorityInterceptorApiProperty;
import com.smedi.ismedi.authority.starter.util.AuthorityUtil;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Enumeration;

import static com.smedi.ismedi.authority.starter.context.CurrentUserHelper.tokenContext;

/**
 * 检验当前服务是否包含了ticket
 */
@Slf4j
@ComponentScan({"com.smedi.ismedi.authority.starter.feign"})
@Order(Ordered.HIGHEST_PRECEDENCE)
public class AuthorityHandler implements HandlerInterceptor {

    private static final String USER_ID = "userId";

    @Autowired
    AuthorityAccessFeignClient authorityAccessFeignClient;

    @Autowired
    AuthorityUtil authorityUtil;

    @Autowired
    AuthorityInterceptorApiProperty authorityInterceptorApiProperty;

    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
//        // 装载工具
//        BeanFactory factory = WebApplicationContextUtils.getRequiredWebApplicationContext(httpServletRequest.getServletContext());
//        if (authorityAccessFeignClient == null) {
//            authorityAccessFeignClient = factory.getBean(AuthorityAccessFeignClient.class);
//        }
//        if (authorityUtil == null) {
//            authorityUtil = factory.getBean(AuthorityUtil.class);
//        }
//
//        log.debug("skipAuthority: {}", httpServletRequest.getSession().getAttribute(AuthorityConstant.skipAuthority));
//        log.debug("token: {}", authorityUtil.getAccessTokenWithNoThrown());
//        log.debug("线程id：{}", Thread.currentThread().getId());
//
//        // 获取是否包含了跨域设置
//        Object value = httpServletRequest.getSession().getAttribute(AuthorityConstant.skipAuthority);
//        boolean skipAuthority = false;
//        if (value != null) {
//            skipAuthority = Boolean.parseBoolean(value.toString());
//        }
//        log.info("uri: {} >>> 跳过验证: {}", httpServletRequest.getRequestURI(), skipAuthority);

        if (authorityInterceptorApiProperty.isAuthenticate()) {
            validateToken(httpServletRequest, tokenContext.get());
        }

        // 修改打了skipAuthority,如果Token有问题，则不显示报错
//        if (!skipAuthority) {
//            // 获取请求的token
//            String token = authorityUtil.getAccessToken();
//            if (authorityInterceptorApiProperty.isPrintLog()) {
//                log.info("拦截token >>> {}：{}", AuthorityConstant.ISMEDI_ACCESS_TOKEN, token);
//            }
//
//            validateToken(httpServletRequest, token);
//        } else {
//            String token = authorityUtil.getAccessTokenWithNoThrown();
//            if (!StringUtils.isEmpty(token)) {
//                try {
//                    validateToken(httpServletRequest, token);
//                } catch (Exception e) {
//                    // 不进行校验
//                }
//            }
//        }

//        Enumeration<String> headerNames = httpServletRequest.getHeaderNames();
//        while (headerNames.hasMoreElements()) {
//            String attribute = headerNames.nextElement();
//            log.debug(" header ---> attribute: {}, value: {}", attribute, httpServletRequest.getHeader(attribute));
//        }

        // 加入日志需要的用户token
//        String logToken = authorityUtil.getAccessTokenWithNoThrown();
        MDC.put(USER_ID, tokenContext.get());

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object
            o, ModelAndView modelAndView) throws Exception {
        // logger.info("--------------处理请求完成后视图渲染之前的处理操作---------------");

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse
            httpServletResponse, Object o, Exception e) throws Exception {
        // 删除日志需要的用户token
        MDC.remove(USER_ID);
        // logger.info("---------------视图渲染之后的操作-------------------------0");
    }

    /**
     * 验证token令牌
     *
     * @param httpServletRequest
     * @param token
     */
    private void validateToken(HttpServletRequest httpServletRequest, String token) {
        // 判断票据是否有效
        ResponseData<Object> responseData = authorityAccessFeignClient.getValidateTokenAndGetAuthorityAccessAndRefreshExpress(token);
        if (!responseData.isSuccess()) {
            throw LogicException.raise(BasicError.TOKEN_INVALID, responseData.getApplication(), responseData.getErrorMsg().toString());
        }
    }
}
